{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Numpy计算逆矩阵求解线性方程组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于这样的线性方程组：\n",
    "* x + y + z = 6\n",
    "* 2y + 5z = -4\n",
    "* 2x + 5y - z = 27\n",
    "\n",
    "可以表示成矩阵的形式：\n",
    "<img style=\"margin-left:0px\" src=\"./other_files/numpy-array-inv.jpg\" />\n",
    "\n",
    "用公式可以表示为：Ax=b，其中A是矩阵，x和b都是列向量\n",
    "\n",
    "***逆矩阵（inverse matrix）的定义：***  \n",
    "设A是数域上的一个n阶矩阵，若存在另一个n阶矩阵B，使得： AB=BA=E ，则我们称B是A的逆矩阵，而A则被称为可逆矩阵。注：E为单位矩阵。\n",
    "\n",
    "***使用逆矩阵求解线性方程组的方法：***  \n",
    "两边都乘以$A^{-1}$，变成$A^{-1}$Ax=$A^{-1}$b，因为任何矩阵乘以单位矩阵都是自身，所以x=$A^{-1}$b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. 求解逆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1,  1,  1],\n",
       "       [ 0,  2,  5],\n",
       "       [ 2,  5, -1]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.array([\n",
    "    [1,1,1],\n",
    "    [0,2,5],\n",
    "    [2,5,-1]\n",
    "])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.28571429, -0.28571429, -0.14285714],\n",
       "       [-0.47619048,  0.14285714,  0.23809524],\n",
       "       [ 0.19047619,  0.14285714, -0.0952381 ]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# B为A的逆矩阵\n",
    "B = np.linalg.inv(A)\n",
    "B"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 验证矩阵和逆矩阵的乘积是单位矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.00000000e+00, -2.77555756e-17,  2.77555756e-17],\n",
       "       [ 0.00000000e+00,  1.00000000e+00,  0.00000000e+00],\n",
       "       [-2.22044605e-16,  5.55111512e-17,  1.00000000e+00]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A@B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.00000000e+00, -2.77555756e-17,  2.77555756e-17],\n",
       "       [ 0.00000000e+00,  1.00000000e+00,  0.00000000e+00],\n",
       "       [-2.22044605e-16,  5.55111512e-17,  1.00000000e+00]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.matmul(A, B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 验证线性方程组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造Ax=b中的b\n",
    "b = np.array([6, -4, 27])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用逆矩阵求解x\n",
    "x = B@b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5.,  3., -2.])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 6., -4., 27.])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 验证A@x = b\n",
    "A@x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
